/*
 * Copyright (c) 2024 Syntiant Corp.  All rights reserved.
 * Contact at http://www.syntiant.com
 *
 * This software is available to you under a choice of one of two licenses.
 * You may choose to be licensed under the terms of the GNU General Public
 * License (GPL) Version 2, available from the file LICENSE in the main
 * directory of this source tree, or the OpenIB.org BSD license below.  Any
 * code involving Linux software will require selection of the GNU General
 * Public License (GPL) Version 2.
 *
 * OPENIB.ORG BSD LICENSE
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 	** SDK: v112.3.5-Samsung **
*/


#ifndef NDP120_DSP_MAILBOX_H_
#define NDP120_DSP_MAILBOX_H_

typedef uint32_t ndp120_dsp_mailbox_msg_t;

#define NDP120_DSP_MB_PAYLOAD_SHIFT 0
#define NDP120_DSP_MB_PAYLOAD_MASK  0xFFFF
#define NDP120_DSP_MB_MESSAGE_SHIFT 0x10
#define NDP120_DSP_MB_MESSAGE_MASK  0xFF
#define NDP120_DSP_MB_SEQ_SHIFT     0x18
#define NDP120_DSP_MB_SEQ_MASK      0x3F
#define NDP120_DSP_MB_TYPE_SHIFT    0x1E
#define NDP120_DSP_MB_TYPE_MASK     0x1
#define NDP120_DSP_MB_TOGGLE_SHIFT  0x1F
#define NDP120_DSP_MB_TOGGLE_MASK   0x1
#define NDP120_H2D_MB_PAYLOAD_SHIFT 0x10
#define NDP120_H2D_MB_PAYLOAD_MASK  0xFFFF

#define NDP120_M2D_MB_EXT_PARAMS_SHIFT  (16)
#define NDP120_M2D_MB_EXT_PARAMS_MASK   (0xFFFF)
#define NDP120_M2D_MB_SET_EXT_PARAMS(x1, x2)     ((x1) |\
    (((x2) & NDP120_M2D_MB_EXT_PARAMS_MASK) << NDP120_M2D_MB_EXT_PARAMS_SHIFT))

#define NDP120_DSP_MB_GET_PAYLOAD(x)        ((x >> NDP120_DSP_MB_PAYLOAD_SHIFT) & NDP120_DSP_MB_PAYLOAD_MASK)
#define NDP120_DSP_MB_SET_PAYLOAD(x, y)     ((x & ~(NDP120_DSP_MB_PAYLOAD_MASK << NDP120_DSP_MB_PAYLOAD_SHIFT)) | (((y) & NDP120_DSP_MB_PAYLOAD_MASK) << NDP120_DSP_MB_PAYLOAD_SHIFT))

#define NDP120_DSP_MB_GET_MESSAGE(x)        ((x >> NDP120_DSP_MB_MESSAGE_SHIFT) & NDP120_DSP_MB_MESSAGE_MASK)
#define NDP120_DSP_MB_SET_MESSAGE(x, y)     ((x & ~(NDP120_DSP_MB_MESSAGE_MASK << NDP120_DSP_MB_MESSAGE_SHIFT)) | (((y) & NDP120_DSP_MB_MESSAGE_MASK) << NDP120_DSP_MB_MESSAGE_SHIFT))

#define NDP120_DSP_MB_GET_SEQ(x)            ((x >> NDP120_DSP_MB_SEQ_SHIFT) & NDP120_DSP_MB_SEQ_MASK)
#define NDP120_DSP_MB_SET_SEQ(x, y)         ((x & ~(NDP120_DSP_MB_SEQ_MASK << NDP120_DSP_MB_SEQ_SHIFT)) | (((y) & NDP120_DSP_MB_SEQ_MASK) << NDP120_DSP_MB_SEQ_SHIFT))

#define NDP120_DSP_MB_GET_TYPE(x)           ((x >> NDP120_DSP_MB_TYPE_SHIFT) & NDP120_DSP_MB_TYPE_MASK)
#define NDP120_DSP_MB_SET_TYPE(x, y)        ((x & ~(NDP120_DSP_MB_TYPE_MASK << NDP120_DSP_MB_TYPE_SHIFT)) | (((y) & NDP120_DSP_MB_TYPE_MASK) << NDP120_DSP_MB_TYPE_SHIFT))

#define NDP120_DSP_MB_GET_TOGGLE(x)         ((x >> NDP120_DSP_MB_TOGGLE_SHIFT) & NDP120_DSP_MB_TOGGLE_MASK)
#define NDP120_DSP_MB_SET_TOGGLE(x, y)      ((x & ~(NDP120_DSP_MB_TOGGLE_MASK << NDP120_DSP_MB_TOGGLE_SHIFT)) | (((y) & NDP120_DSP_MB_TOGGLE_MASK) << NDP120_DSP_MB_TOGGLE_SHIFT))

#define NDP120_H2D_MB_GET_PAYLOAD(x)        ((x >> NDP120_H2D_MB_PAYLOAD_SHIFT) & NDP120_H2D_MB_PAYLOAD_MASK)
#define NDP120_H2D_MB_SET_PAYLOAD(x, y)     ((x & ~(NDP120_H2D_MB_PAYLOAD_MASK << NDP120_H2D_MB_PAYLOAD_SHIFT)) | (((y) & NDP120_H2D_MB_PAYLOAD_MASK) << NDP120_H2D_MB_PAYLOAD_SHIFT))

#define NDP120_DSP_MB_NOTIFY_PAYLOAD_GPIO_CHANGE_GPIO_SHIFT 0
#define NDP120_DSP_MB_NOTIFY_PAYLOAD_GPIO_CHANGE_GPIO_MASK 0x1F
#define NDP120_DSP_MB_NOTIFY_PAYLOAD_GPIO_CHANGE_STATE_SHIFT 0x5
#define NDP120_DSP_MB_NOTIFY_PAYLOAD_GPIO_CHANGE_STATE_MASK 0x1

#define NDP120_DSP_MB_NOTIFY_PAYLOAD_GPIO_CHANGE_GET_GPIO(x) \
        ((x >> NDP120_DSP_MB_NOTIFY_PAYLOAD_GPIO_CHANGE_GPIO_SHIFT) & NDP120_DSP_MB_NOTIFY_PAYLOAD_GPIO_CHANGE_GPIO_MASK)

#define NDP120_DSP_MB_NOTIFY_PAYLOAD_GPIO_CHANGE_SET_GPIO(x,y) \
        ((x & ~(NDP120_DSP_MB_NOTIFY_PAYLOAD_GPIO_CHANGE_GPIO_MASK << NDP120_DSP_MB_NOTIFY_PAYLOAD_GPIO_CHANGE_GPIO_SHIFT)) | \
        (((y) & NDP120_DSP_MB_NOTIFY_PAYLOAD_GPIO_CHANGE_GPIO_MASK) << NDP120_DSP_MB_NOTIFY_PAYLOAD_GPIO_CHANGE_GPIO_SHIFT))

#define NDP120_DSP_MB_NOTIFY_PAYLOAD_GPIO_CHANGE_GET_STATE(x) \
        ((x >> NDP120_DSP_MB_NOTIFY_PAYLOAD_GPIO_CHANGE_STATE_SHIFT) & NDP120_DSP_MB_NOTIFY_PAYLOAD_GPIO_CHANGE_STATE_MASK)

#define NDP120_DSP_MB_NOTIFY_PAYLOAD_GPIO_CHANGE_SET_STATE(x,y) \
        ((x & ~(NDP120_DSP_MB_NOTIFY_PAYLOAD_GPIO_CHANGE_STATE_MASK << NDP120_DSP_MB_NOTIFY_PAYLOAD_GPIO_CHANGE_STATE_SHIFT)) | \
        (((y) & NDP120_DSP_MB_NOTIFY_PAYLOAD_GPIO_CHANGE_STATE_MASK) << NDP120_DSP_MB_NOTIFY_PAYLOAD_GPIO_CHANGE_STATE_SHIFT))

#define NDP120_MCU_OPEN_RAM_START       (0x20007400U)
#define NDP120_MCU_OPEN_RAM_RESULTS     (0x20007500U)

/*Results returned from MCU & DSP are of same length*/
#define NDP120_OPEN_RAM_RESULTS_LEN (256)

#define NDP120_DSP_OPEN_RAM_START       (NDP120_MCU_OPEN_RAM_RESULTS + NDP120_OPEN_RAM_RESULTS_LEN)
#define NDP120_DSP_OPEN_RAM_RESULTS     (NDP120_DSP_OPEN_RAM_START + NDP120_OPEN_RAM_RESULTS_LEN)

#define NDP120_DSP_MB_H2D_ADDR     (NDP120_MCU_OPEN_RAM_START)
#define NDP120_DSP_MB_H2D_SIZE     (8)
#define NDP120_DSP_MB_H2D_WORDS    (2)

#define NDP120_DSP_MB_D2H_ADDR     (NDP120_DSP_MB_H2D_ADDR + NDP120_DSP_MB_H2D_SIZE)
#define NDP120_DSP_MB_D2H_SIZE     (4)

/* MCU -> DSP REQ */
enum {
    /* req */
    NDP120_DSP_MB_M2D_PING                  = 0x00,
    NDP120_DSP_MB_M2D_ADX_UPPER             = 0x04,
    NDP120_DSP_MB_M2D_ADX_LOWER             = 0x05,
    NDP120_DSP_MB_M2D_INIT_FLOW_AUDIO       = 0x06,
    NDP120_DSP_MB_M2D_INIT_FLOW_FEATURE     = 0x07,
    NDP120_DSP_MB_M2D_DSP_START             = 0x08,
    NDP120_DSP_MB_M2D_EXTENDED_MB           = 0x09,
    /* Extended MB messages */
    NDP120_DSP_MB_M2D_EXTENDED_MB_START     = 0x90,
    NDP120_DSP_MB_M2D_DSP_MODE_CHANGE       = NDP120_DSP_MB_M2D_EXTENDED_MB_START,
    NDP120_DSP_MB_M2D_DNN_DATA_CLEANUP      = 0x91,
    NDP120_DSP_MB_M2D_SENSOR_SET            = 0x92,
    NDP120_DSP_MB_M2D_WFI_DISABLE           = 0x93,
    NDP120_DSP_MB_M2D_ALGO_CONFIG_ALLOC     = 0x94,
    NDP120_DSP_MB_M2D_EXTENDED_MB_END       = 0x95,

    /* resp */
    NDP120_DSP_MB_D2M_PONG                  = NDP120_DSP_MB_M2D_PING,
    NDP120_DSP_MB_D2M_ADX_UPPER             = NDP120_DSP_MB_M2D_ADX_UPPER,
    NDP120_DSP_MB_D2M_ADX_LOWER             = NDP120_DSP_MB_M2D_ADX_LOWER,
    NDP120_DSP_MB_D2M_INIT_FLOW_AUDIO       = NDP120_DSP_MB_M2D_INIT_FLOW_AUDIO,
    NDP120_DSP_MB_D2M_INIT_FLOW_FEATURE     = NDP120_DSP_MB_M2D_INIT_FLOW_FEATURE,
    NDP120_DSP_MB_D2M_DSP_START             = NDP120_DSP_MB_M2D_DSP_START,
    NDP120_DSP_MB_D2M_DSP_MODE_CHANGE       = NDP120_DSP_MB_M2D_DSP_MODE_CHANGE,
    NDP120_DSP_MB_D2M_SENSOR_SET            = NDP120_DSP_MB_M2D_SENSOR_SET,
    NDP120_DSP_MB_D2M_WFI_DISABLE           = NDP120_DSP_MB_M2D_WFI_DISABLE
};

/* DSP -> MCU REQ */
enum {
    /* req */
    NDP120_DSP_MB_D2M_PING                  = 0x00,
    NDP120_DSP_MB_D2M_NN_DONE               = 0x01,
    NDP120_DSP_MB_D2M_GPIO_CHANGE_LOW       = 0x02,
    NDP120_DSP_MB_D2M_GPIO_CHANGE_HIGH      = 0x03,
    NDP120_DSP_MB_D2M_HEARTBEAT             = 0x04,
    NDP120_DSP_MB_D2M_RESET_POSTERIOR       = 0x05,
    NDP120_DSP_MB_D2M_FETCH_STRENGTH_ADDR   = 0x06,
    NDP120_DSP_MB_D2M_ALGO_REPORT_MATCH     = 0x07,

    /* resp */
    NDP120_DSP_MB_M2D_PONG                  = 0x00,
    NDP120_DSP_MB_M2D_NN_DONE               = NDP120_DSP_MB_D2M_NN_DONE,
    NDP120_DSP_MB_M2D_GPIO_CHANGE_LOW       = NDP120_DSP_MB_D2M_GPIO_CHANGE_LOW,
    NDP120_DSP_MB_M2D_GPIO_CHANGE_HIGH      = NDP120_DSP_MB_D2M_GPIO_CHANGE_HIGH,
    NDP120_DSP_MB_M2D_HEARTBEAT             = NDP120_DSP_MB_D2M_HEARTBEAT,
    NDP120_DSP_MB_M2D_FETCH_STRENGTH_ADDR   = NDP120_DSP_MB_D2M_FETCH_STRENGTH_ADDR,
    NDP120_DSP_MB_M2D_NN_NOT_LOADED         = 0xAE
};

/* HOST -> DSP REQ */

enum {
    /* if you change the below, updated the code in
     syntiant_ndp120_do_mailbox_req_no_sync() in ILIB */

    /* req */
    /* NO values lower than 0x0A.  0x00 --> 0x09 are
       reserved my the MCU */
    NDP120_DSP_MB_H2D_RESTART               = 0x0A,
    NDP120_DSP_MB_H2D_ADX_UPPER             = 0x0B,
    NDP120_DSP_MB_H2D_ADX_LOWER             = 0x0C,
    NDP120_DSP_MB_H2D_MODE_CHANGE           = 0x0D,

    /* Value below is for an "extended" message, which
     will be placed in "NDP120_DSP_MAILBOX_ADDR" those enums are
     NDP120_DSP_MB_H2D_EXT_* */
    NDP120_DSP_MB_H2D_EXT                   = 0x0E,
    NDP120_DSP_MB_D2H_EXT                   = NDP120_DSP_MB_H2D_EXT,

    /* First extended message */
    NDP120_DSP_MB_H2D_EXT_NN_LOAD_COMPLETE  = 0x0F,
    NDP120_DSP_MB_H2D_EXT__START__          = NDP120_DSP_MB_H2D_EXT_NN_LOAD_COMPLETE,
    NDP120_DSP_MB_H2D_EXT_SET_TANK_SIZE     = 0x10,
    NDP120_DSP_MB_H2D_REQUEST_NOP           = 0x11,
    NDP120_DSP_MB_H2D_EXT_SENSOR_SET        = 0x12,
    NDP120_DSP_MB_H2D_EXT_VAD_CONTROL       = 0x13,
    NDP120_DSP_MB_H2D_EXT_WFI_CONTROL       = 0x14,
    NDP120_DSP_MB_H2D_EXT_ALGO_CONFIG_ALLOC = 0x15,
    NDP120_DSP_MB_H2D_EXT_RESET_ALGO_CONFIG = 0x16,
    NDP120_DSP_MB_H2D_EXT_MCU_CLK_DIV       = 0x17,
    NDP120_DSP_MB_H2D_EXT_SET_DSP_DEBUG     = 0x18,
    NDP120_DSP_MB_H2D_EXT_SENSOR_CONTROL    = 0x19,
    NDP120_DSP_MB_H2D_EXT_AUTO_CLK_SCALING  = 0x1A,
    NDP120_DSP_MB_H2D_EXT_GET_NN_INPUT_TYPE = 0x1B,
    NDP120_DSP_MB_H2D_EXT_RW_POWER_PROFILE  = 0x1C,
    NDP120_DSP_MB_H2D_EXT_INIT_RING_BUF_PTR = 0X1D,
    NDP120_DSP_MB_H2D_EXT_READ_DNN_STATE    = 0x1E,
    NDP120_DSP_MB_H2D_EXT_SET_DNN_RUN_DELAY = 0x1F,
    NDP120_DSP_MB_H2D_EXT_SENSOR_INIT       = 0x20,
    NDP120_DSP_MB_H2D_EXT_GET_AUDIO_PARAMS  = 0x21,
    NDP120_DSP_MB_H2D_EXT_SET_ID            = 0x22,
    NDP120_DSP_MB_H2D_EXT_GET_INFO          = 0x23,
    NDP120_DSP_MB_H2D_EXT_MISC_INPUT_SIZE   = 0x24,
    NDP120_DSP_MB_H2D_EXT_SET_BARGE_IN      = 0x25,
    NDP120_DSP_MB_H2D_EXT_GET_MEM_INFO      = 0x26,
    NDP120_DSP_MB_H2D_EXT__END__            = 0x2F,

    /* resp */
    NDP120_DSP_MB_D2H_RESTART               = NDP120_DSP_MB_H2D_RESTART,
    NDP120_DSP_MB_D2H_ADX_UPPER             = NDP120_DSP_MB_H2D_ADX_UPPER,
    NDP120_DSP_MB_D2H_ADX_LOWER             = NDP120_DSP_MB_H2D_ADX_LOWER,
    NDP120_DSP_MB_D2H_MODE_CHANGE           = NDP120_DSP_MB_H2D_MODE_CHANGE,
    NDP120_DSP_MB_D2H_RESP_NOP              = NDP120_DSP_MB_H2D_REQUEST_NOP
};

/* DSP -> HOST REQ */
enum {
    /* req */
    /* IMPORTANT
       Values below that require a reply must be in the range of 0xA - 0x0F
       and cannot overlap with tne NDP_DSP_MB_H2D values above */

    NDP120_DSP_MB_D2H_WATERMARK             = 0x0F,
    NDP120_DSP_MB_D2H_EXTRACT_READY         = 0x10,
    NDP120_DSP_MB_D2H_RUNNING               = 0x12,
    NDP120_DSP_MB_D2H_DEBUG                 = 0x13,
    NDP120_DSP_MB_D2H_ALGO_ERROR_INIT       = 0x14,
    NDP120_DSP_MB_D2H_ALGO_ERROR_PROCESS    = 0x15,
    NDP120_DSP_MB_D2H_NO_DNN_MEM            = 0x16,
    NDP120_DSP_MB_D2H_NO_DSP_MEM            = 0x17,
    NDP120_DSP_MB_D2H_NO_VAD_MIC            = 0x18,
    NDP120_DSP_MB_D2H_UNKNOWN_MIC_STATE     = 0x19,
    NDP120_DSP_MB_D2H_EXTRACT_DELAY_ERROR   = 0x21,

    /* resp */
    NDP120_DSP_MB_H2D_WATERMARK             = NDP120_DSP_MB_D2H_WATERMARK,
    NDP120_DSP_MB_H2D_EXTRACT_READY         = NDP120_DSP_MB_D2H_EXTRACT_READY,
    NDP120_DSP_MB_H2D_RUNNING               = NDP120_DSP_MB_D2H_RUNNING,
    NDP120_DSP_MB_H2D_DEBUG                 = NDP120_DSP_MB_D2H_DEBUG,
    NDP120_DSP_MB_H2D_ALGO_ERROR_INIT       = NDP120_DSP_MB_D2H_ALGO_ERROR_INIT,
    NDP120_DSP_MB_H2D_UNKNOWN_MIC_STATE     = NDP120_DSP_MB_D2H_UNKNOWN_MIC_STATE
};


enum {
    MB_REQ  = 0,
    MB_RESP = 1
};

enum {
    NDP120_D2M_INVALID_REQ = 0xBAD4,
    NDP120_D2H_INVALID_REQ = 0xDEAD
};

#endif
